import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;


class LeafCellEditor extends DefaultTreeCellEditor {

  public LeafCellEditor(JTree tree, DefaultTreeCellRenderer renderer, TreeCellEditor editor) {
    super(tree, renderer, editor);
  }

  public boolean isCellEditable(EventObject event) {
    boolean returnValue = super.isCellEditable(event);
    if (returnValue) {
      Object node = tree.getLastSelectedPathComponent();
      if ((node != null) && (node instanceof TreeNode)) {
        TreeNode treeNode = (TreeNode) node;
        returnValue = treeNode.isLeaf();
      }
    }
    return returnValue;
  }
}

class CheckBoxNodeRenderer implements TreeCellRenderer {
  private JCheckBox leafRenderer = new JCheckBox();

  private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

  protected JCheckBox getLeafRenderer() {
    return leafRenderer;
  }
  
  protected DefaultTreeCellRenderer getNoneLeafRenderer()
  {
	  return nonLeafRenderer;
  }

  public CheckBoxNodeRenderer() {
    Font fontValue;
    fontValue = UIManager.getFont("Tree.font");
    if (fontValue != null) {
      leafRenderer.setFont(fontValue);
    }
    Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
    leafRenderer.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));
    
    nonLeafRenderer.setOpenIcon(UIManager.getIcon("FileView.computerIcon"));
    nonLeafRenderer.setClosedIcon(UIManager.getIcon("FileView.computerIcon"));
  }

  public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
      boolean expanded, boolean leaf, int row, boolean hasFocus) {

    Component returnValue;
    if (leaf) 
    {
      String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, false);
      leafRenderer.setText(stringValue);
      leafRenderer.setSelected(false);
      leafRenderer.setEnabled(tree.isEnabled());
      if ((value != null) && (value instanceof MonitorDataNode)) 
      {
    	  MonitorDataNode monitorDataNode = (MonitorDataNode) value;
          leafRenderer.setText(monitorDataNode.getText());
          leafRenderer.setSelected(monitorDataNode.getIsSelected());
          if(!monitorDataNode.getIsAlive())
          {
        	  leafRenderer.setBackground(Color.RED);
        	  leafRenderer.setEnabled(false);
        	  leafRenderer.setForeground(Color.BLACK);
          }
          else
          {
        	  leafRenderer.setBackground(Color.WHITE);
        	  leafRenderer.setEnabled(true);
          }
      }
      returnValue = leafRenderer;
    } 
  	else 
  	{
  		returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value, selected, expanded,
          leaf, row, hasFocus);
      	if((value != null) && (value instanceof AgentNode))
    	{
      		AgentNode agentNode = (AgentNode)value;
      		if(!agentNode.getIsAlive())
      		{
      			nonLeafRenderer.setBackground(Color.RED);
      		}
      		else
      		{
      			nonLeafRenderer.setBackground(Color.WHITE);
      		}
    	}
      
    }
    return returnValue;
  }
}

class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
  CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();

  ChangeEvent changeEvent = null;

  JTree tree;

  public CheckBoxNodeEditor(JTree tree) {
    this.tree = tree;
  }

  public Object getCellEditorValue() {
    JCheckBox checkbox = renderer.getLeafRenderer();

    Object lastPathComp = tree.getSelectionPath().getLastPathComponent();
    if(lastPathComp instanceof MonitorDataNode)
    {
    	MonitorDataNode monitorDataNode = (MonitorDataNode)lastPathComp;
    	monitorDataNode.setIsSelected(checkbox.isSelected());
    	monitorDataNode.setText(checkbox.getText());
    	return monitorDataNode;
    }
    if(lastPathComp instanceof AgentNode)
    {
    	DefaultTreeCellRenderer nonLeafRenderer = renderer.getNoneLeafRenderer();
    	AgentNode agentNode = (AgentNode)lastPathComp;
    	agentNode.setIsAlive(nonLeafRenderer.getBackground()!=Color.RED);
    }
    return lastPathComp; 
  }

  public boolean isCellEditable(EventObject event) {
    boolean returnValue = false;
    if (event instanceof MouseEvent) {
      MouseEvent mouseEvent = (MouseEvent) event;
      TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
      if (path != null) 
      {
        Object node = path.getLastPathComponent();
        if ((node != null) && (node instanceof MonitorDataNode)) {
        	MonitorDataNode monitorDataNode = (MonitorDataNode) node;
        	returnValue = monitorDataNode.isLeaf();
        }
      }
    }
    return returnValue;
  }

  public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected,
      boolean expanded, boolean leaf, int row) {

    Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf,
        row, true);

    ItemListener itemListener = new ItemListener() {
      public void itemStateChanged(ItemEvent itemEvent) {
        if (stopCellEditing()) {
          fireEditingStopped();
        }
      }
    };
    if (editor instanceof JCheckBox) {
      ((JCheckBox) editor).addItemListener(itemListener);
    }
    return editor;
  }
}
